package com.mlk.cash.service;

import cn.hutool.core.util.IdUtil;
import com.github.binarywang.wxpay.bean.entpay.EntPayRequest;
import com.github.binarywang.wxpay.bean.entpay.EntPayResult;
import com.github.binarywang.wxpay.exception.WxPayException;
import com.github.binarywang.wxpay.service.WxPayService;
import com.google.common.collect.Maps;
import com.mlk.constant.EngConstant;
import com.mlk.core.exception.GlobalException;
import com.mlk.core.util.IPUtils;
import com.mlk.core.util.ServerResponse;
import com.mlk.core.util.SpringUtils;
import com.mlk.engSystem.constant.SystemParam;
import com.mlk.engSystem.service.EngSysParamService;
import com.mlk.engUser.mapper.EngUserMapper;
import com.mlk.engUser.po.EngUser;
import com.mlk.score.mapper.EngOutScoreMapper;
import com.mlk.score.po.EngOutScore;
import com.mlk.wx.WxPayProperties;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.Date;
import java.util.Map;

@Service
@Slf4j
public class CashServiceImpl implements CashService{

    @Resource
    private EngUserMapper engUserMapper;

    @Resource
    private EngSysParamService engSysParamService;

    @Resource
    private EngOutScoreMapper engOutScoreMapper;

    @Override
    public ServerResponse getCashRate(String openId) {
        EngUser user = this.engUserMapper.selectOne(EngUser.builder().openId(openId).build());
        BigDecimal rate = this.engSysParamService.getBigDecimalValue(SystemParam.SCORE_TO_MONEY_RATE);
        Map<String,Object> result = Maps.newHashMap();
        result.put("user",user);
        result.put("rate",rate);
        return ServerResponse.ok(result);
    }


    @Resource
    private WxPayProperties properties;

    /**
     * 积分兑现
     * @param openId
     * @param amount
     * @return
     */
    @Override
    @Transactional
    public ServerResponse doCash(String openId, Integer amount) {

        EngUser user = this.engUserMapper.selectOne(EngUser.builder().openId(openId).build());
        if(user.getScore() < amount){
            throw new GlobalException("您的积分不足");
        }

        // 计算换去的钱
        // 获取积分比例
        BigDecimal rate = this.engSysParamService.getBigDecimalValue(SystemParam.SCORE_TO_MONEY_RATE);
        Double remain = rate.doubleValue()*amount;

        if(remain < 0.3 || remain >200){
            throw new GlobalException("积分兑换的金额需要0.3到200之间");
        }

        // 下面执行企业支付的功能
        EntPayRequest request = new EntPayRequest();
        request.setMchAppid(properties.getAppId());
        request.setMchId(properties.getMchId());
        // 这个写死就好了-- 需要是随机的---咱们没有退款的功能...
        request.setPartnerTradeNo(String.valueOf(IdUtil.createSnowflake(3L,3L).nextId()));
        request.setOpenid(user.getOpenId()); // openId
        request.setCheckName("NO_CHECK");
        // 转换到int值
        // request.setAmount((int)(verify.getAmount().doubleValue()*100));
        // 测试环境下 就支付三毛钱


        request.setAmount((int) (remain * 100));



        request.setDescription("能源宝积分兑现");
        request.setSpbillCreateIp(IPUtils.getInstance().getIpAddr());

        EntPayResult entPayResult =null;
        try {
            entPayResult = SpringUtils.getBean(WxPayService.class).getEntPayService().entPay(request);
        } catch (WxPayException e) {
            log.error("微信转账失败",e);
            throw new GlobalException("微信转账失败:"+e.getErrCodeDes());
        }

        // 必须这两个字段同时返回SUCCESS
        if((!StringUtils.equals(entPayResult.getErrCode(),"SUCCESS")) || (!StringUtils.equals(entPayResult.getResultCode(),"SUCCESS"))){
            throw new GlobalException("微信支付出现错误"+entPayResult);
        }

        // 下面就需要给用户减去积分数
        int count = this.engUserMapper.addUserScore(openId,(-1)*amount);
        if(count== 0){
            throw new GlobalException("积分兑现失败");
        }

        // 操作 out_score
        EngOutScore outScore = new EngOutScore();
        outScore.setOpenId(openId);
        outScore.setCreateTime(new Date());
        outScore.setNum(amount);
        outScore.setType(EngConstant.OUT_SCORE_TARGET.CASH_SCORE);
        count = this.engOutScoreMapper.insert(outScore);
        if(count== 0){
            throw new GlobalException("积分兑现失败");
        }
        return ServerResponse.ok("操作成功");
    }
}
